package org.example.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.example.BlogServiceApi;
import org.example.constant.Constants;
import org.example.convert.BeanConvert;
import org.example.exception.BlogException;
import org.example.mapper.UserInfoMapper;
import org.example.model.UserInfo;
import org.example.pojo.*;
import org.example.service.UserService;
import org.example.utils.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private BlogServiceApi blogService;
    @Autowired
    private BlogServiceApi blogServiceApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 之所以使用redis是因为，将RedisTemplate这个给封装到里面了
     */
    @Autowired
    private Redis redis;

    private static final long EXPIRE_TIME = 14 * 24 * 60 * 60;
    private static final String USER_PREFIX = "user";

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    public UserLoginResponse login(UserInfoRequest user) {
        //验证账号密码是否正确
        UserInfo userInfo = selectUserInfoByName(user.getUserName());
        if (userInfo==null || userInfo.getId()==null){
            throw new BlogException("用户不存在");
        }
//        if (!user.getPassword().equals(userInfo.getPassword())){
//            throw new BlogException("用户密码不正确");
//        }
        if (!SecurityUtil.verify(user.getPassword(),userInfo.getPassword())){
            throw new BlogException("用户密码不正确");
        }
        //账号密码正确的逻辑
        Map<String,Object> claims = new HashMap<>();
        claims.put("id", userInfo.getId());
        claims.put("name", userInfo.getUserName());

        String jwt = JWTUtils.genJwt(claims);
        return new UserLoginResponse(userInfo.getId(), jwt);
    }

    @Override
    public UserInfoResponse getUserInfo(Integer userId) {
        UserInfoResponse userInfoResponse = new UserInfoResponse();
        UserInfo userInfo = selectUserInfoById(userId);
        BeanUtils.copyProperties(userInfo, userInfoResponse);
        return userInfoResponse;
    }

    @Override
    public UserInfoResponse selectAuthorInfoByBlogId(Integer blogId) {
        //这里进行远程调用 返回的用户信息
        UserInfoResponse userInfoResponse = new UserInfoResponse();
        Result<BlogInfoResponse> blogDeatail = blogServiceApi.getBlogDeatail(blogId);
        System.out.println(blogDeatail.getData());
        if(blogDeatail==null || blogDeatail.getData()==null) {
            throw new  BlogException("博客不存在");
        }
        UserInfo userInfo = selectUserInfoById(blogDeatail.getData().getUserId());
        BeanUtils.copyProperties(userInfo, userInfoResponse);
        return userInfoResponse;
    }

    /**
     * 实现注册的功能，返回的是用户的id
     * @param user
     * @return
     */
    @Override
    public Integer registerUser(UserInfoRegisterRequest user) {
        //首先，先检验用户是不是已经存在了
        checkInfo(user);
        UserInfo userInfo = BeanConvert.convert(user);
        try{
            String encrypt = SecurityUtil.encrypt(userInfo.getPassword());
            userInfo.setPassword(encrypt);
            int inserted = userInfoMapper.insert(userInfo);
            log.info("id为："+userInfo.getId()+" 用户名为："+userInfo.getUserName());
            if(inserted==1) {
                redis.setKey(buildKey(user.getUserName()), JsonUtils.toJson(userInfo),EXPIRE_TIME);
                userInfo.setPassword("");
                //之后这里就要给邮箱发送消息了
                //这里给rabbitmq发送信息，监听方收到消息后就会进行执行相应的逻辑
                rabbitTemplate.convertAndSend(Constants.USER_EXCHANGE_NAME,"",JsonUtils.toJson(userInfo));
                return userInfo.getId();
            }else {
                throw new BlogException("用户注册失败");
            }
        } catch (Exception e) {
            log.info("用户注册失败");
            throw new BlogException("用户注册失败");
        }
    }

    private String buildKey(String userName) {
       return redis.buildKey(USER_PREFIX, userName);
    }

    private void checkInfo(UserInfoRegisterRequest user) {
        UserInfo userInfo = selectUserInfoByName(user.getUserName());
        if(userInfo!=null) {
            throw new BlogException("用户已经存在");
        }
        // TODO 用于邮箱的检验和url的检验
        if (!RegexUtil.checkMail(user.getEmail())){
            throw new BlogException("邮箱格式不合法");
        }
        if (!RegexUtil.checkUrl(user.getGithubUrl())){
            throw new BlogException("githubUrl格式不合法");
        }
    }


    public UserInfo selectUserInfoByName(String userName) {
        return userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                .eq(UserInfo::getUserName, userName).eq(UserInfo::getDeleteFlag, 0));
    }
    private UserInfo selectUserInfoById(Integer userId) {
        return userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                .eq(UserInfo::getId, userId).eq(UserInfo::getDeleteFlag, 0));
    }
}
